﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;

namespace AdbRegisterUtils
{
    public class CmdTerminalService : IDisposable
    {
        private Process _process;
        private StreamWriter _inputWriter;
        private readonly Action<string, string> _outputHandler;
        private readonly ProcessStartInfo _startInfo;
        private readonly Queue<string> _outputBuffer = new Queue<string>();
        private readonly object _bufferLock = new object();
        private bool _isDisposed = false;
        private const int MAX_BUFFER_SIZE = 1000; // 防止缓冲区无限增长

        public CmdTerminalService(Action<string, string> outputHandler, ProcessStartInfo startInfo = null)
        {
            _outputHandler = outputHandler ?? throw new ArgumentNullException(nameof(outputHandler));
            _startInfo = startInfo ?? ProcessStartInfoManager.GetDefaultCmdStartInfo();

            Initialize();
        }

        private void Initialize()
        {
            try
            {
                StartProcess();
                Console.WriteLine("CMD 终端已启动");
            }
            catch (Exception ex)
            {
                throw new Exception($"初始化CMD终端服务失败: {ex.Message}", ex);
            }
        }

        private void StartProcess()
        {
            _process = new Process();
            _process.StartInfo = _startInfo;

            _process.OutputDataReceived += (sender, e) =>
            {
                if (!string.IsNullOrEmpty(e.Data))
                {
                    ProcessOutput(e.Data);
                }
            };

            _process.ErrorDataReceived += (sender, e) =>
            {
                if (!string.IsNullOrEmpty(e.Data))
                {
                    ProcessOutput($"[ERROR] {e.Data}");
                }
            };

            _process.Start();
            _inputWriter = _process.StandardInput;

            _process.BeginOutputReadLine();
            _process.BeginErrorReadLine();
        }

        private void ProcessOutput(string data)
        {
            lock (_bufferLock)
            {
                // 添加到缓冲区
                _outputBuffer.Enqueue(data);

                // 限制缓冲区大小
                while (_outputBuffer.Count > MAX_BUFFER_SIZE)
                {
                    _outputBuffer.Dequeue();
                }
            }

            // 调用输出处理器
            _outputHandler?.Invoke("Output", data);
        }

        /// <summary>
        /// 发送命令到终端
        /// </summary>
        public void SendCommand(string command)
        {
            if (_isDisposed)
                throw new ObjectDisposedException(nameof(CmdTerminalService));

            if (_inputWriter != null && !_inputWriter.BaseStream.CanWrite)
                throw new InvalidOperationException("无法写入到输入流");

            try
            {
                _inputWriter.WriteLine(command);
                _inputWriter.Flush();
                Console.WriteLine($"已发送命令: {command}");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送命令失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 清空输出缓冲区
        /// </summary>
        public void ClearOutputBuffer()
        {
            lock (_bufferLock)
            {
                int clearedCount = _outputBuffer.Count;
                _outputBuffer.Clear();
                Console.WriteLine($"输出缓冲区已清空，清除了 {clearedCount} 行数据");
            }
        }

        /// <summary>
        /// 获取当前缓冲区中的输出行数
        /// </summary>
        public int GetBufferLineCount()
        {
            lock (_bufferLock)
            {
                return _outputBuffer.Count;
            }
        }

        /// <summary>
        /// 获取缓冲区内容（用于调试）
        /// </summary>
        public string[] GetBufferContents()
        {
            lock (_bufferLock)
            {
                return _outputBuffer.ToArray();
            }
        }

        /// <summary>
        /// 重置终端服务（停止当前进程并重新启动）
        /// </summary>
        public void ResetTerminal()
        {
            if (_isDisposed)
                throw new ObjectDisposedException(nameof(CmdTerminalService));

            try
            {
                // 停止当前进程
                if (_process != null && !_process.HasExited)
                {
                    _process.Kill();
                    Thread.Sleep(200);
                }

                // 清空缓冲区
                ClearOutputBuffer();

                // 重新启动进程
                StartProcess();

                Console.WriteLine("终端服务已重置");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"重置终端服务时出错: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 停止当前运行的命令（发送Ctrl+C）
        /// </summary>
        public void StopCurrentCommand()
        {
            try
            {
                SendCommand("\x3"); // Ctrl+C
                Thread.Sleep(100);
                ClearOutputBuffer();
                Console.WriteLine("当前命令已停止");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"停止当前命令时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 检查终端是否正在运行
        /// </summary>
        public bool IsRunning => !_isDisposed && _process != null && !_process.HasExited;

        /// <summary>
        /// 释放资源
        /// </summary>
        public void Dispose()
        {
            if (!_isDisposed)
            {
                try
                {
                    if (_process != null)
                    {
                        if (!_process.HasExited)
                        {
                            // 尝试正常退出
                            try
                            {
                                _inputWriter?.WriteLine("exit");
                                _inputWriter?.Flush();

                                if (!_process.WaitForExit(2000))
                                {
                                    _process.Kill();
                                }
                            }
                            catch
                            {
                                // 忽略退出时的异常
                            }
                        }

                        _process.Dispose();
                    }

                    _inputWriter?.Dispose();
                    ClearOutputBuffer();
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"释放终端服务资源时出错: {ex.Message}");
                }
                finally
                {
                    _isDisposed = true;
                }
            }
        }
    }
}